package main

import (
	"reflect"
	"fmt"
)

type student struct {
	Name   string
	Number int
	Height uint
	Weight float64
}

func (s student) Info() {
	fmt.Printf("Name:\t%s\n", s.Name)
	fmt.Printf("Number:\t%03d\n", s.Number)
	fmt.Printf("Height:\t%d cm\n", s.Height)
	fmt.Printf("Weight:\t%.2f kg\n", s.Weight)
}

func (s *student) SetHeightWeight(h uint, w float64) {
	s.Height = h
	s.Weight = w
}

func main() {
	s1 := student{"Jimmy", 1, 170, 65.5}
	// 遍历字段属性
	st1 := reflect.TypeOf(s1)
	for i := 0; i < st1.NumField(); i++{
		fmt.Println("字段属性：", st1.Field(i).Name, st1.Field(i).Type)
	}
	// 遍历字段的值
	sv1 := reflect.ValueOf(s1)
	for i := 0; i < sv1.NumField(); i++{
		fmt.Println("字段值: ", sv1.Field(i))
	}
	s2 := student{"Mary", 2, 160, 45.5}
	st2 := reflect.TypeOf(s2)
	sv2 := reflect.ValueOf(&s2)  // 这里传了指针
	// 遍历字段的属性和值
	for i := 0; i < st2.NumField(); i++{
		v := sv2.Elem().Field(i)  // 这里如果不取指针的值，会Panic
		fmt.Printf("%v(%v): %v\n", st2.Field(i).Name, st2.Field(i).Type, v)
	}
}
/* 输出结果
字段属性： Name string
字段属性： Number int
字段属性： Height uint
字段属性： Weight float64
字段值:  Jimmy
字段值:  1
字段值:  170
字段值:  65.5
Name(string): Mary
Number(int): 2
Height(uint): 160
Weight(float64): 45.5
*/